<template>
  <div class="chat-content-container" id="chat-content">
    <div class="container-header">
      <h3>{{ currentRoom.name }}</h3>
      <n-space>
        <n-tooltip>
          <template #trigger>
            <n-button quaternary circle @click="toBottom" size="large">
              <template #icon>
                <n-icon><CaretDownCircleOutline /></n-icon>
              </template>
            </n-button>
          </template>
          回到底部
        </n-tooltip>
        <n-dropdown v-if="!userShow || !groupShow" trigger="click" :options="options" @select="handleSelect">
          <n-button v-if="!userShow || !groupShow" quaternary circle color="#dedfe0" size="large">
            <template #icon>
              <n-icon color="black"><MenuFoldOutlined /></n-icon>
            </template>
          </n-button>
        </n-dropdown>
      </n-space>
    </div>

    <virtual-list
      ref="virtualRef"
      class="container-content"
      :style="{ 'height': contentHeight, 'overflow-y': 'auto' }"
      :data-key="'id'"
      :data-sources="messageList"
      :data-component="Message"
      :estimate-size="80"
      :keeps="10"
      @totop="loadHistoryMessage">
      <template #header>
        <div class="virtual-header" v-show="!virtualStatus.can2Top">
          <n-spin size="small" class="loader">
            <template #icon>
              <n-icon><Reload /></n-icon>
            </template>
            <template #description>
              努力加载中...
            </template>
          </n-spin>
        </div>
      </template>
    </virtual-list>

    <div class="container-footer">
      <n-tooltip>
        <template #trigger>
          <n-button circle @click="atHandler">
            <template #icon>
              <n-icon><At /></n-icon>
            </template>
          </n-button>
        </template>
        点击可自动添加与AI聊天的关键词
      </n-tooltip>
      <n-input
        ref="inputRef"
        v-model:value="inputMessage"
        @keydown="keydownHandler"
        autofocus round
        type="textarea"
        :autosize="{ maxRows: 1 }"
        placeholder="来加入聊天吧~"
      />
      <n-button strong round type="success" @click="sendMessage">
        <template #icon>
          <n-icon><ChatbubbleOutline /></n-icon>
        </template>
      </n-button>
    </div>

    <n-drawer
      v-model:show="drawerDetail.active"
      to="#chat-content"
      :width="drawerDetail.width[drawerDetail.type]"
      :placement="drawerDetail.placement[drawerDetail.type]"
    >
      <n-drawer-content :body-style="drawerDetail.bodyStyle">
        <ChatGroupList v-if="drawerDetail.type === 0" />
        <ChatUserList v-if="drawerDetail.type === 1" />
      </n-drawer-content>
    </n-drawer>
  </div>
</template>

<script lang="ts" setup>
import { onMounted, onBeforeUnmount, reactive, ref, watch, defineProps, computed, nextTick } from "vue";
import { formatToDateTimeUTC } from "@/utils/dateUtil";
import { MenuFoldOutlined } from '@vicons/antd';
// @ts-ignore
import { ChatbubbleOutline, Reload, At, CaretDownCircleOutline } from '@vicons/ionicons5'
import ChatGroupList from "@/views/worker/chat/ChatGroupList/index.vue";
import ChatUserList from "@/views/worker/chat/ChatUserList/index.vue";
// @ts-ignore
import VirtualList from 'vue3-virtual-scroll-list';
import Message from '@/views/worker/chat/ChatContent/Message.vue';
import { useImChatStore, EventEnum } from "@/store/modules/imchat";
import { useUserStore } from "@/store/modules/user";
import { useGlobSetting } from "@/hooks/setting";
import { storeToRefs } from "pinia";

const imchatStore = useImChatStore()
const { urlPrefix } = useGlobSetting()
const { username, getUserInfo } = useUserStore()
const { currentRoom, messageList } = storeToRefs(imchatStore)
const virtualRef = ref()
const props = defineProps({
  groupShow: {
    type: Boolean,
    default: false
  },
  userShow: {
    type: Boolean,
    default: false
  }
})
const virtualStatus = reactive({
  can2Top: true,      // 是否可以滚动到顶部进行加载
  can2Bottom: true,   // 是否可以滚动到底部
})

const options = computed(() => {
  let arr: any[] = []
  if (!props.groupShow) {
    arr.push({
      label: '聊天室列表',
      key: 0
    })
  }
  if (!props.userShow) {
    arr.push({
      label: '用户在线列表',
      key: 1
    })
  }
  return arr
})
const drawerDetail = reactive({
  active: false,
  placement: ['left', 'right'],
  title: ['聊天室列表', '用户在线列表'],
  type: 0,
  width: [325, 190],
  bodyStyle: {
    padding: '0',
    height: '100%',
  }
})
const toBottom = () => {
  virtualStatus.can2Bottom = true;
  msgVirtualList2Btm();
}

const contentHeight = ref('410px')

const handleSelect = key => {
  drawerDetail.type = key;
  drawerDetail.active = true;
}

// -------- 获取历史消息(向上加载)
const loadHistoryMessage = async () => {
  if (!virtualStatus.can2Top) return;
  virtualStatus.can2Bottom = false;
  virtualStatus.can2Top = false;
  try {
    let size = await imchatStore.loadMessageList()
    if (size > 0) {
      await nextTick(() => {
        virtualRef.value.scrollToIndex(size - 1);
      });
    }
  } finally {
    virtualStatus.can2Top = true;
  }
}

// -------- virtual-handler
const msgVirtualList2Btm = () => {
  if (virtualRef.value && virtualStatus.can2Bottom) {
    virtualRef.value.scrollToBottom();
  }
};
const msgVirtualList2Idx = (idx: number) => {
  if (virtualRef.value) {
    virtualRef.value.scrollToIndex(idx >= 0 ? idx : 0);
  }
};
const msgVirtualList2Offset = (offset: number) => {
  if (virtualRef.value) {
    virtualRef.value.scrollToOffset(offset);
  }
};

// -------- 消息处理
watch(
  () => messageList.value.length,
  () => nextTick(() => msgVirtualList2Btm())
);
const inputRef = ref()
const inputMessage = ref('')
const keydownHandler = e => {
  if (e.keyCode !== 229) {
    if (e.shiftKey && e.keyCode === 13) {
      // 借由 textarea 自带的特性，按下 shift + enter 可以换行，不需要手动添加 \n
      return
    }
    if (e.keyCode === 13) {
      // 这里需要阻止默认事件，否则会触发换行动作
      e.preventDefault()
      sendMessage()
      return
    }
  }
}
const atHandler = () => {
  if (!inputMessage.value.trim().startsWith('@AI')) {
    inputMessage.value = '@AI ' + inputMessage.value
  }
  inputRef.value.focus()
}
const sendMessage = () => {
  if (!inputMessage.value.trim()) return;
  let o = {
    // @ts-ignore
    userId: getUserInfo.id,
    // @ts-ignore
    username: getUserInfo.username,
    // @ts-ignore
    avatar: getUserInfo.avatar,
    // @ts-ignore
    roomId: currentRoom.value.id,
    content: inputMessage.value,
    replyId: null,
    gapCount: null,
    sendTime: formatToDateTimeUTC(new Date())
  }
  imchatStore.emitEvent(EventEnum.MESSAGE, o)
  inputMessage.value = '';
  // 发送消息后，可滚动到底部
  virtualStatus.can2Bottom = true
}

const resizeHandler = () => {
  // 对消息列表进行高度计算
  contentHeight.value = `${document.body.clientHeight - 118 - 60 - 54 - 20}px`;
  // 变化的时候将抽屉关闭
  drawerDetail.active = false;
}

onMounted(() => {
  window.addEventListener('resize', resizeHandler)
  resizeHandler()
  msgVirtualList2Btm()
})

onBeforeUnmount(() => {
  window.removeEventListener('resize', resizeHandler)
})
</script>

<style lang="less" scoped>
.chat-content-container {
  height: 100%;
  position: relative;
  border-radius: 10px;
  background-color: #E5E4E4;

  .container-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    border-radius: 10px 10px 0 0;
    background-color: #F5F5F5;

    h3 {
      font-size: 22px;
      text-align: center;
      margin: 0;
      padding-left: 15px;
      line-height: 60px;
    }
  }

  :deep(.n-scrollbar) {
    width: auto;
  }

  :deep(div[class="container-content n-scrollbar"]) {
    box-sizing:content-box;
    margin: 0 15px;
    background-color: #FFFFFF;
    border-radius: 10px;
  }

  .container-content {
    scrollbar-width: thin;

    .virtual-header {
      padding: 5px 0;
      font-size: 13px;
      background-color: #FFFFFF;
      border-radius: 10px 10px 0 0;

      .loader {
        display: flex;
        flex-direction: inherit;

        :deep(.n-spin-description) {
          margin: 0 0 0 10px;
        }
      }
    }
  }

  .container-footer {
    width: 100%;
    box-sizing: border-box;
    position: absolute;
    bottom: 0;
    display: flex;
    justify-content: space-between;
    padding: 10px 20px;
    -webkit-column-gap: 20px;
    -moz-column-gap: 20px;
    column-gap: 20px;
    align-items: center;
    border-radius: 0 0 10px 10px;
    background-color: #F5F5F5;
  }
}

</style>
